package com.yilin.platform.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yilin.platform.base_core.commons.exception.BusinessException;
import com.yilin.platform.base_core.commons.utils.DateTimeUtil;
import com.yilin.platform.base_core.commons.utils.MapUtil;
import com.yilin.platform.base_core.commons.utils.ParamUtil;
import com.yilin.platform.base_core.commons.utils.StringUtil;
import com.yilin.platform.controller.BankPabController;
import com.yilin.platform.entity.aliPay.AliPayTradeRecord;
import com.yilin.platform.entity.capital.TradeFlow;
import com.yilin.platform.entity.user.AccountConfigure;
import com.yilin.platform.entity.user.deserialize.HatchAlipay;
import com.yilin.platform.entity.weChat.WeChatTradeRecord;
import com.yilin.platform.mapper.aliPay.AliPayTradeRecordMapper;
import com.yilin.platform.service.IAliPayService;
import com.yilin.platform.service.IUserService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class AliPayService extends ServiceImpl<AliPayTradeRecordMapper, AliPayTradeRecord> implements IAliPayService {

    private Logger logger = LoggerFactory.getLogger(AliPayService.class);
    @Value("${plat-product-code}")
    private String platProductCode;//平台产品代码
    @Resource
    private IUserService userService;
    @Resource
    private TradeFlowService tradeFlowService;
    @Resource
    private AliPayTradeRecordMapper aliPayTradeRecordMapper;
    private HatchAlipay hatchAlipay;

    public HatchAlipay getHatchAlipay() {
        if (hatchAlipay == null) { // 第一次检查，未创建时进入同步块
            synchronized (this) {
                if (hatchAlipay == null) { // 双重检查，确保只有一个线程创建对象
                    Map<String, Object> param = MapUtil.generate(map -> map.put("productCode", platProductCode));
                    hatchAlipay = userService.request("/user/hatch/getAlipayHatchByCode", null, param, new TypeToken<HatchAlipay>() {
                    });
                }
            }
        }
        return hatchAlipay;
    }

    //获取支付宝客户端程序
    public AlipayClient getAlipayClient(String userType) throws AlipayApiException {
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");//
        certAlipayRequest.setAppId(getHatchAlipay().getAlipayAppId(userType));
        certAlipayRequest.setPrivateKey(getHatchAlipay().getRsa2PrivateKey(userType));
        certAlipayRequest.setFormat("JSON");
        certAlipayRequest.setCharset("UTF-8");
        certAlipayRequest.setSignType("RSA2");
        certAlipayRequest.setCertPath(getHatchAlipay().getRsa2PublicKeyPath(userType));//设置支付宝公钥证书路径
        certAlipayRequest.setAlipayPublicCertPath(getHatchAlipay().getRsa2CertFolderPath(userType));////设置应用公钥证书路径
        certAlipayRequest.setRootCertPath(getHatchAlipay().getRsa2RootCertFolderPath(userType));///设置支付宝根证书路径
        return new DefaultAlipayClient(certAlipayRequest);
    }

    /**
     * 生成预付单
     * 下单系统
     */
    @Transactional
    @Override
    public String generatorAliPayOrder(AliPayTradeRecord tradeRecord) {

        // 注意：不同接口这里的请求对象是不同的，这个可以查看蚂蚁金服开放平台的API文档查看
        AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
        alipayRequest.setApiVersion("2.0");
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setOutTradeNo(tradeRecord.getTradeNo());//商户网站唯一订单号。
        model.setTotalAmount(String.valueOf(tradeRecord.getTranAmount()));//支付金额
        model.setSubject(tradeRecord.getTradeName());//交易名称
        model.setProductCode("QUICK_MSECURITY_PAY");
        alipayRequest.setBizModel(model);
        String userType = String.valueOf(tradeRecord.getUserType());
        alipayRequest.setNotifyUrl(getHatchAlipay().getAliPayBackUrl() + "/platform/alipay/aliPayBack/" + userType);
        try {
            logger.info("支付宝app支付下单请求数据" + new Gson().toJson(alipayRequest));
            AlipayTradeAppPayResponse alipayResponse = getAlipayClient(String.valueOf(tradeRecord.getUserType())).sdkExecute(alipayRequest);
            logger.info("支付宝app支付下单返回数据" + new Gson().toJson(alipayResponse));
            // 返回支付相关信息(此处可以直接将getBody中的内容直接返回，无需再做一些其他操作)
            if (alipayResponse.isSuccess()) {
                tradeRecord.setInitiateTime(new Date());
                tradeRecord.setAliPayType(AliPayTradeRecord.AliPayType.app);
                tradeRecord.setAliPayTradeType(AliPayTradeRecord.AliPayTradeType.payment);
                tradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.handle);
                tradeRecord.setBankFlowNo(alipayResponse.getTradeNo());
                tradeRecord.setInAcctNo(alipayResponse.getSellerId());
                tradeRecord.setQueryWaitCount(0);
                tradeRecord.setSyncTaskCount(0);
                tradeRecord.setNextWaitTime(new Date());
                tradeRecord.setNextNotificationTime(new Date());
                aliPayTradeRecordMapper.insert(tradeRecord);
                return alipayResponse.getBody();
            } else {
                throw new BusinessException(alipayResponse.getSubMsg());
            }
        } catch (AlipayApiException e) {
            logger.error("支付宝app支付下单请求异常" + e.getErrMsg());
            throw new BusinessException("支付宝下单异常：" + e.getErrMsg());
        }
    }

    /**
     * 支付宝支付：交易结果查询
     */
    @Transactional
    @Override
    public AliPayTradeRecord queryAliPayOrder(String tradeNo) {
        AliPayTradeRecord tradeRecord = getAliPayTradeRecordByTradeNo(tradeNo);
        int time = DateTimeUtil.secondBetween(tradeRecord.getInitiateTime(), new Date());
        if (time <= 10) throw new BusinessException("支付宝正在处理中，请稍后查询");
        ParamUtil.isNull(tradeRecord, "获取支付单失败");
        try {
            AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();
            AlipayTradeQueryModel model = new AlipayTradeQueryModel();
            model.setOutTradeNo(tradeRecord.getTradeNo());
            alipayTradeQueryRequest.setBizModel(model);
            logger.info("支付宝app支付易结果查询请求数据" + new Gson().toJson(alipayTradeQueryRequest));
            AlipayTradeQueryResponse alipayTradeQueryResponse = getAlipayClient(String.valueOf(tradeRecord.getUserType())).certificateExecute(alipayTradeQueryRequest);
            if (alipayTradeQueryResponse.isSuccess() && alipayTradeQueryResponse.getCode().equals("10000")) {
                if (alipayTradeQueryResponse.getTradeStatus().equals("TRADE_SUCCESS") || alipayTradeQueryResponse.getTradeStatus().equals("TRADE_FINISHED")) {
                    tradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.success);
                    tradeRecord.setCompleteTime(alipayTradeQueryResponse.getSendPayDate());
                } else if (alipayTradeQueryResponse.getTradeStatus().equals("WAIT_BUYER_PAY")) {
                    tradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.notpay);
                } else if (alipayTradeQueryResponse.getTradeStatus().equals("TRADE_CLOSED")) {
                    tradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.close);
                } else {
                    tradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.handle);
                }
                if (tradeRecord.getOutAcctNo() == null)
                    tradeRecord.setOutAcctNo(alipayTradeQueryResponse.getBuyerUserId());
                if (tradeRecord.getBankFlowNo() == null)
                    tradeRecord.setBankFlowNo(alipayTradeQueryResponse.getTradeNo());
                saveTradeFlow(tradeRecord.getTradeName(), tradeRecord);
                saveOrUpdate(tradeRecord);
                return tradeRecord;
            } else {
                throw new BusinessException(alipayTradeQueryResponse.getSubMsg() == null ? alipayTradeQueryResponse.getMsg() : alipayTradeQueryResponse.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw new BusinessException("支付宝订单查询失败,请稍后再试" + e.getMessage());
        }
    }

    /**
     * 【支付退款】
     */
    @Override
    public AliPayTradeRecord aliPayRefund(AliPayTradeRecord aliPayTradeRecord, AliPayTradeRecord aliPayTradeRecordOrging) {
        AlipayTradeRefundApplyModel model = new AlipayTradeRefundApplyModel();
        model.setOutTradeNo(aliPayTradeRecordOrging.getTradeNo());
        model.setTradeNo(aliPayTradeRecordOrging.getBankFlowNo());
        model.setRefundAmount(String.valueOf(aliPayTradeRecord.getTranAmount()));
        model.setRefundReason(aliPayTradeRecord.getRemark());
        model.setOutRequestNo(aliPayTradeRecord.getTradeNo());
        aliPayTradeRecord.setAliPayType(aliPayTradeRecordOrging.getAliPayType());
        AlipayTradeRefundRequest alipayTradeRefundRequest = new AlipayTradeRefundRequest();
        alipayTradeRefundRequest.setBizModel(model);
        String userType = String.valueOf(aliPayTradeRecord.getUserType());
        alipayTradeRefundRequest.setNotifyUrl(getHatchAlipay().getAliPayBackUrl() + "/platform/alipay/aliRefundBack/" + userType);//支付宝回调已弃用
        try {
            logger.info("支付宝app支付退款请求数据" + new Gson().toJson(alipayTradeRefundRequest));
            AlipayTradeRefundResponse response = getAlipayClient(String.valueOf(aliPayTradeRecordOrging.getUserType())).certificateExecute(alipayTradeRefundRequest);
            logger.info("支付宝app支付退款返回数据" + new Gson().toJson(alipayTradeRefundRequest));
            aliPayTradeRecord.setInAcctNo(aliPayTradeRecordOrging.getOutAcctNo());
            aliPayTradeRecord.setOutAcctNo(aliPayTradeRecordOrging.getInAcctNo());
            if (response.isSuccess() && response.getCode().equals("10000") && response.getFundChange().equals("Y")) {
                aliPayTradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.success);
                aliPayTradeRecord.setAliPayTradeType(AliPayTradeRecord.AliPayTradeType.refund);
                aliPayTradeRecord.setInitiateTime(new Date());
                aliPayTradeRecord.setCompleteTime(new Date());
                aliPayTradeRecord.setBankFlowNo(response.getTradeNo());
            } else {
                aliPayTradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.fail);
                aliPayTradeRecord.setBankMsg(response.getSubMsg());
            }
            aliPayTradeRecord.setQueryWaitCount(0);
            aliPayTradeRecord.setSyncTaskCount(0);
            aliPayTradeRecord.setNextWaitTime(new Date());
            aliPayTradeRecord.setNextNotificationTime(new Date());
            aliPayTradeRecord.setUserType(aliPayTradeRecordOrging.getUserType());
            saveOrUpdate(aliPayTradeRecord);
            if (aliPayTradeRecord.getAliPayTradeStatus() == AliPayTradeRecord.AliPayTradeStatus.success) {
                processNotificationStatus(Collections.singletonList(aliPayTradeRecord));
            }
            return aliPayTradeRecord;
        } catch (Exception e) {
            throw new BusinessException("支付宝退款异常，失败原因：{" + e.getMessage() + "}");
        }
    }

    /**
     * 【支付退款查询】
     * 备注：调这个方法之后需要掉用订单通知接口
     */
    @Override
    public AliPayTradeRecord aliPayRefundQuery(String tradeNo) {
        AliPayTradeRecord aliPayTradeRecord = getAliPayTradeRecordByTradeNo(tradeNo);
        int time = DateTimeUtil.secondBetween(aliPayTradeRecord.getInitiateTime(), new Date());
        if (time <= 10) throw new BusinessException("支付宝正在处理中，请稍后查询");
        ParamUtil.isNull(aliPayTradeRecord, "获取支付单失败");
        AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
        model.setOutTradeNo(aliPayTradeRecord.getRefundOriginalTradeNo());
        model.setOutRequestNo(aliPayTradeRecord.getTradeNo());
        AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
        request.setBizModel(model);
        try {
            logger.info("支付宝app支付退款查询请求数据" + new Gson().toJson(request));
            AlipayTradeFastpayRefundQueryResponse response = getAlipayClient(String.valueOf(aliPayTradeRecord.getUserType())).certificateExecute(request);
            if (response.isSuccess() && response.getCode().equals("10000")) {
                if (response.getRefundStatus().equals("REFUND_SUCCESS")) {
                    aliPayTradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.success);
                    Date comTime = response.getGmtRefundPay() != null ? response.getGmtRefundPay() : new Date();
                    if (aliPayTradeRecord.getCompleteTime() == null) aliPayTradeRecord.setCompleteTime(comTime);
                    aliPayTradeRecord.setBankFlowNo(response.getTradeNo());
                } else {
                    aliPayTradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.fail);
                }
            }
            saveTradeFlow(aliPayTradeRecord.getTradeName(), aliPayTradeRecord);
            saveOrUpdate(aliPayTradeRecord);
            return aliPayTradeRecord;
        } catch (Exception e) {
            throw new BusinessException("查询支付宝查询退款异常，失败原因：{" + e.getMessage() + "}");
        }
    }
    //############################################PC端支付##################################################################

    /**
     * 生成预付单
     * 下单系统
     */
    @Override
    public String generatorAliPayOrderPcH5(AliPayTradeRecord aliPayTradeRecord, String requestFromURl) {
        // 注意：不同接口这里的请求对象是不同的，这个可以查看蚂蚁金服开放平台的API文档查看
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setApiVersion("2.0");
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(aliPayTradeRecord.getTradeNo());//商户网站唯一订单号。
        model.setTotalAmount(String.valueOf(aliPayTradeRecord.getTranAmount()));//支付金额
        model.setSubject(aliPayTradeRecord.getTradeName());//交易名称
        model.setRequestFromUrl(requestFromURl);
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        alipayRequest.setBizModel(model);
        alipayRequest.setReturnUrl(requestFromURl);
        String userType = String.valueOf(aliPayTradeRecord.getUserType());
        alipayRequest.setNotifyUrl(getHatchAlipay().getAliPayBackUrl() + "/platform/alipay/aliPayBack/" + userType);
        // 注意：每个请求的相应对象不同，与请求对象是对应。
        try {
            logger.info("支付宝PCH5支付下单请求数据" + new Gson().toJson(alipayRequest));
            AlipayTradePagePayResponse alipayResponse = getAlipayClient(String.valueOf(aliPayTradeRecord.getUserType())).pageExecute(alipayRequest);
            logger.info("支付宝PCH5支付下单返回数据" + new Gson().toJson(alipayResponse));
            // 返回支付相关信息(此处可以直接将getBody中的内容直接返回，无需再做一些其他操作)
            if (alipayResponse.isSuccess()) {
                aliPayTradeRecord.setInitiateTime(new Date());
                aliPayTradeRecord.setAliPayType(AliPayTradeRecord.AliPayType.web);
                aliPayTradeRecord.setAliPayTradeType(AliPayTradeRecord.AliPayTradeType.payment);
                aliPayTradeRecord.setBankFlowNo(alipayResponse.getTradeNo());
                if (aliPayTradeRecord.getInAcctNo() == null)
                    aliPayTradeRecord.setInAcctNo(alipayResponse.getSellerId());
                aliPayTradeRecord.setQueryWaitCount(0);
                aliPayTradeRecord.setSyncTaskCount(0);
                aliPayTradeRecord.setNextWaitTime(new Date());
                aliPayTradeRecord.setNextNotificationTime(new Date());
                saveOrUpdate(aliPayTradeRecord);
                return alipayResponse.getBody();
            } else {
                throw new BusinessException(alipayResponse.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw new BusinessException(e.getErrMsg());
        }
    }

    @Override
    public Map<String, Object> aliPayNotity(HttpServletRequest request, String userType, String payType) {
        Map<String, Object> map = new HashMap<>();
        map.put("status", "fail");
        try {
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = iter.next();
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                logger.info(">>>>>参数" + name + ":" + valueStr);
                params.put(name, valueStr);
            }
            logger.info("支付宝验签数据：" + new Gson().toJson(params));
            boolean signVerified = AlipaySignature.rsaCertCheckV1(params, getHatchAlipay().getRsa2CertFolderPath(userType), "UTF-8", "RSA2");
            if (!signVerified) {
                logger.error("支付宝验签失败数据：" + new Gson().toJson(params));
                return map;
            }
            //这里退款和支付的逻辑一样可以合并
            logger.info("支付宝支付回调数数据" + new Gson().toJson(params));
            String tradeNo = params.get("out_trade_no");
            AliPayTradeRecord aliPayTradeRecord = null;
            if (Objects.equals(payType, "payment")) {
                aliPayTradeRecord = getAliPayTradeRecordByTradeNo(tradeNo);
            } else if (Objects.equals(payType, "refund")) {
                aliPayTradeRecord = getAliPayTradeRecordByRefundTradeNo(tradeNo);
            }
            ParamUtil.isNull(aliPayTradeRecord, "数据库未找到该订单号");
            String status = params.get("trade_status");
            aliPayTradeRecord.setBankFlowNo(params.get("trade_no"));
            if (aliPayTradeRecord.getAliPayTradeType() == AliPayTradeRecord.AliPayTradeType.payment) {
                aliPayTradeRecord.setCompleteTime(params.get("gmt_payment") == null ? new Date() : DateTimeUtil.stringToDate(String.valueOf(params.get("gmt_payment")), null));
            } else if (aliPayTradeRecord.getAliPayTradeType() == AliPayTradeRecord.AliPayTradeType.refund) {
                aliPayTradeRecord.setCompleteTime(params.get("gmt_refund") == null ? new Date() : DateTimeUtil.stringToDate(String.valueOf(params.get("gmt_refund")), null));
            } else {
                aliPayTradeRecord.setCompleteTime(new Date());
            }
            if (params.get("buyer_id") != null) aliPayTradeRecord.setOutAcctNo(params.get("buyer_id"));
            if (params.get("seller_id") != null) aliPayTradeRecord.setInAcctNo(params.get("seller_id"));
            if (status.equals("WAIT_BUYER_PAY")) {
                aliPayTradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.notpay);
            } else if (status.equals("TRADE_CLOSED")) {
                aliPayTradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.close);
            } else if (status.equals("TRADE_SUCCESS") || status.equals("TRADE_FINISHED")) {
                aliPayTradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.success);
            } else {
                aliPayTradeRecord.setAliPayTradeStatus(AliPayTradeRecord.AliPayTradeStatus.handle);
            }
            try {
                saveTradeFlow(aliPayTradeRecord.getTradeName(), aliPayTradeRecord);
            } catch (Exception e) {
                logger.error("支付宝回调保存流水异常" + e.getMessage());
            }
            saveOrUpdate(aliPayTradeRecord);
            try {
                processNotificationStatus(Collections.singletonList(aliPayTradeRecord));
            } catch (Exception e) {
                logger.error("支付宝回调通知易林订单失败" + e.getMessage());
            }
            map.put("status", "success");
            return map;
        } catch (AlipayApiException e) {
            logger.error("支付宝APP回调错误，错误信息" + e.getErrMsg());
            return map;
        }
    }

    @Override
    public AliPayTradeRecord getAliPayTradeRecordById(String tradeRecordId) {
        return aliPayTradeRecordMapper.selectById(tradeRecordId);
    }

    @Override
    public AliPayTradeRecord getAliPayTradeRecordByTradeNo(String tradeNo) {
        QueryWrapper<AliPayTradeRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("trade_no", tradeNo);
        queryWrapper.eq("is_deleted", 0);
        return aliPayTradeRecordMapper.selectOne(queryWrapper);
    }

    @Override
    public AliPayTradeRecord getAliPayTradeRecordByRefundTradeNo(String tradeNo) {
        QueryWrapper<AliPayTradeRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("refund_original_trade_no", tradeNo);
        queryWrapper.eq("is_deleted", 0);
        return aliPayTradeRecordMapper.selectOne(queryWrapper);
    }

    @Override
    public List<AliPayTradeRecord> getNotificationList() {
        QueryWrapper<AliPayTradeRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.nested(i ->
                        i.or(j -> j.in("ali_pay_trade_status", 3, 5).le("next_wait_time", new Date()))
                                .or(j -> j.eq("ali_pay_trade_status", 1).eq("notified_yilin", 0))
                                .or(j -> j.eq("ali_pay_trade_status", 2).eq("notified_yilin", 0))
                                .or(j -> j.eq("ali_pay_trade_status", 4).eq("notified_yilin", 0)))
                .eq("is_deleted", 0)
                .le("next_notification_time", new Date());
        return aliPayTradeRecordMapper.selectList(queryWrapper);
    }

    //    定时函数单笔查询
    @Override
    public void myTaskOneMinute() {
        List<AliPayTradeRecord> recordFlowList = getNotificationList();
        if (recordFlowList == null || recordFlowList.isEmpty()) return;
        List<AliPayTradeRecord> recordSuccess = new ArrayList<>();
        List<AliPayTradeRecord> recordHandle = new ArrayList<>();
        for (AliPayTradeRecord aliPayTradeRecord : recordFlowList) {
            try {
                aliPayTradeRecord = getAliPayTradeRecord(aliPayTradeRecord);
            } catch (Exception e) {
                logger.error("定时函数查询单笔转账异常：" + e.getMessage());
                recordHandle.add(getRecordHandle(aliPayTradeRecord));
                continue;
            }
            if (isSuccessSuccess(aliPayTradeRecord)) {//判断需要通知的
                recordSuccess.add(aliPayTradeRecord);
            } else if (isSuccessHandle(aliPayTradeRecord)) {//判断是否需要重新查询的
                recordHandle.add(getRecordHandle(aliPayTradeRecord));
            }
        }
        if (!recordHandle.isEmpty()) saveOrUpdateBatch(recordHandle);
        if (!recordSuccess.isEmpty()) processNotificationStatus(recordSuccess);
    }


    //#########################################内部方法####################################################
    //通知平台
    private void processNotificationStatus(List<AliPayTradeRecord> recordList) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (int i = 0; i < recordList.size(); i++) {
            String state;
            if (recordList.get(i).getAliPayTradeStatus() == AliPayTradeRecord.AliPayTradeStatus.success) {
                state = "paySuccess";
            }  else if (recordList.get(i).getAliPayTradeStatus() == AliPayTradeRecord.AliPayTradeStatus.close) {
                state = "close";
            } else if (recordList.get(i).getAliPayTradeStatus() == AliPayTradeRecord.AliPayTradeStatus.fail) {
                state = "payFail";
            } else if (recordList.get(i).getAliPayTradeStatus() == AliPayTradeRecord.AliPayTradeStatus.notpay) {
                state = "create";
            } else {
                continue;
            }
            int finalI = i;
            mapList.add(MapUtil.generate(map1 -> {
                map1.put("tradeNo", recordList.get(finalI).getTradeNo());
                map1.put("tradeStatus", state);
                if (StringUtil.isNotEmpty(recordList.get(finalI).getBankFlowNo())) map1.put("bankFlowNo", recordList.get(finalI).getBankFlowNo());
                if (recordList.get(finalI).getCompleteTime() != null) map1.put("finishTime", recordList.get(finalI).getCompleteTime());
                if (StringUtil.isNotEmpty(recordList.get(finalI).getOutAcctNo())) map1.put("paymentCapitalAccount", recordList.get(finalI).getOutAcctNo());
                if (StringUtil.isNotEmpty(recordList.get(finalI).getInAcctNo())) map1.put("incomeCapitalAccount", recordList.get(finalI).getInAcctNo());
                if (StringUtil.isNotEmpty(recordList.get(finalI).getBankMsg()))map1.put("tradeFailMsg", recordList.get(finalI).getBankMsg());
            }));
        }
        if(!mapList.isEmpty())return;
        Map<String, Object> paramMap = MapUtil.generate(map -> {
            map.put("tradeResults", new Gson().toJson(mapList));
            map.put("payType", "alipay");
            map.put("bankType", "none");
        });
        String status = null;
        try {
            status = userService.request("/capital/callback/ailiPayResult", null, paramMap, new TypeToken<String>() {
            });
        } catch (Exception e) {
            handleException(recordList, e);
        }
        if (status == null) return;
        for (AliPayTradeRecord recordFlow : recordList) {
            if (status.equals("SUCCESS")) {
                recordFlow.setSyncTaskCount(0);
                if (recordFlow.getAliPayTradeStatus() != AliPayTradeRecord.AliPayTradeStatus.notpay)
                    recordFlow.setNotifiedYilin(true);
                recordFlow.setNotifyTime(new Date());
            } else {
                updateNotifiWeChatTradeRecordTime(recordFlow);
            }
        }
        saveOrUpdateBatch(recordList);

    }

    //设置通知异常
    private void handleException(List<AliPayTradeRecord> recordList, Exception e) {
        for (AliPayTradeRecord recordFlow : recordList) {
            updateNotifiWeChatTradeRecordTime(recordFlow);
        }
        saveOrUpdateBatch(recordList);
        logger.error("微信通知支付订单失败：错误信息：" + e.getMessage());
        throw new BusinessException(e.getMessage());
    }

    //设置下次通知时间
    private void updateNotifiWeChatTradeRecordTime(AliPayTradeRecord recordFlow) {
        recordFlow.setNextNotificationTime(DateTimeUtil.addTimeByCount(new Date(), recordFlow.getSyncTaskCount()));
        recordFlow.setSyncTaskCount(recordFlow.getSyncTaskCount() + 1);
    }

    //判断需要通知的
    private boolean isSuccessSuccess(AliPayTradeRecord aliPayTradeRecord) {
        return aliPayTradeRecord.getAliPayTradeStatus() != AliPayTradeRecord.AliPayTradeStatus.handle
                && aliPayTradeRecord.getAliPayTradeStatus() != AliPayTradeRecord.AliPayTradeStatus.create
                && aliPayTradeRecord.getAliPayTradeStatus() != AliPayTradeRecord.AliPayTradeStatus.notpay;
    }

    //判断是否需要重新查询的
    private boolean isSuccessHandle(AliPayTradeRecord aliPayTradeRecord) {
        return aliPayTradeRecord.getAliPayTradeStatus() == AliPayTradeRecord.AliPayTradeStatus.handle
                || aliPayTradeRecord.getAliPayTradeStatus() == AliPayTradeRecord.AliPayTradeStatus.notpay;
    }

    //处理生成下次查询时间
    private AliPayTradeRecord getRecordHandle(AliPayTradeRecord aliPayTradeRecord) {
        aliPayTradeRecord.setNextWaitTime(DateTimeUtil.getWeChataAliPayTime(new Date(), aliPayTradeRecord.getQueryWaitCount()));
        aliPayTradeRecord.setQueryWaitCount(aliPayTradeRecord.getQueryWaitCount() + 1);
        return aliPayTradeRecord;
    }

    //    查询支付记录
    private AliPayTradeRecord getAliPayTradeRecord(AliPayTradeRecord aliPayTradeRecord) {
        if (aliPayTradeRecord.getAliPayTradeStatus() == AliPayTradeRecord.AliPayTradeStatus.handle) {
            if (aliPayTradeRecord.getAliPayTradeType() == AliPayTradeRecord.AliPayTradeType.payment) {
                aliPayTradeRecord = queryAliPayOrder(aliPayTradeRecord.getTradeNo());
            } else if (aliPayTradeRecord.getAliPayTradeType() == AliPayTradeRecord.AliPayTradeType.refund) {
                aliPayTradeRecord = aliPayRefundQuery(aliPayTradeRecord.getTradeNo());
            }
        }
        return aliPayTradeRecord;
    }

    //公共: 保存流水
    private void saveTradeFlow(String tradeName, AliPayTradeRecord aliPayTradeRecord) {
        if (aliPayTradeRecord.getAliPayTradeStatus() != AliPayTradeRecord.AliPayTradeStatus.success) return;
        TradeFlow[] tradeFlows = tradeFlowService.generateTradeFlows(tradeName, TradeFlow.PayType.alipay, aliPayTradeRecord);
    }

}
